package example.demo.datasouce;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import java.lang.reflect.Field;
import java.util.Map;

public class DynamicDataSourceRouting extends AbstractRoutingDataSource {

    /**
     * AbstractRoutingDataSource的【Map targetDataSources】等同于AbstractRoutingDataSource的【Map resolvedDataSources】
     * <?  看一下源码，目的就是返回的AbstractRoutingDataSource的【Map targetDataSources】的key
     * determineCurrentLookupKey钩子方法
     * Datasource.getConnection()-->AbstractRoutingDataSource.determineTargetDataSource()
     * -->AbstractRoutingDataSource.determineCurrentLookupKey()-->targetDataSources.get(key)
     */
    @Override
    @SuppressWarnings("unchecked")
    protected Object determineCurrentLookupKey() {
        try {
            Field targetF = this.getClass().getSuperclass().getDeclaredField("targetDataSources");
            targetF.setAccessible(true);
            Map<Object, Object> targetV = (Map<Object, Object>) targetF.get(this);
            //上面的步骤主要是打印使用的数据库，对应的数源源的url

            //有aop作用
            DBTypeEnum ds = DynamicDataSourceContextHolder.getDataSourceType();
            if (ds != null) {
                //使用方式看成C语言的stdio.h的printf函数
                System.out.printf("<<<<<<<<<操作的数据源是【%s】<------>数据源的url是【%s】>>>>>>>>>\n", ds.getDbname(), ((DruidDataSource) targetV.get(ds)).getUrl());
                //返回的是枚举类型
                return DynamicDataSourceContextHolder.getDataSourceType();
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return DBTypeEnum.db1;
    }
}
